package conn

import (
	"golang.org/x/net/websocket"
	"gitee.com/cooge/impush/core"
	"gitee.com/cooge/impush/stream"
	log "github.com/sirupsen/logrus"
	"gitee.com/cooge/impush/message"
	"strconv"
	"time"
)

type WsConn struct {
	conn *websocket.Conn
	userId string
	ms *stream.MessageStream
	liveTime int

}

func NewWsConn(conn *websocket.Conn)*WsConn{
	var ws WsConn
	ws.conn = conn
	ws.liveTime = 30000
	ws.userId = conn.Request().FormValue("id")
	ws.ms=stream.NewMessageStream(conn)
	return &ws
}

func (this *WsConn )Start()  {

	if len(this.userId)==0{
		this.sendMessageBytes(message.StartLogin())
	}else{
		this.SetReadDeadline()
		core.AddUser(this.userId,this)
	}
	for  {
		msg,err:=this.ms.ReadMessage()
		if err!=nil{
			log.Debug(this.userId,"断开连接",err)
			break
		}
		this.handle(msg)

	}
	this.Close(this.userId)
}

func (this *WsConn)Close(userId string)error{
	core.DeleteUser(userId,this)
	return this.ms.Conn.Close()
}

func (this *WsConn)GetUser() string{
	return this.ms.Conn.RemoteAddr().String()
}

func (this *WsConn) sendMessageBytes(b []byte) (int, error) {
	return this.ms.Conn.Write(b)
}
func (this *WsConn) SendMessage(msg *message.Message) (int, error) {
	bs := msg.MessageToByte()
	return this.sendMessageBytes(bs)
}

func (this *WsConn) SetReadDeadline()  {
	this.ms.Conn.SetReadDeadline(time.Now().Add(time.Duration(this.liveTime) * time.Millisecond))
}

func (this *WsConn) handle(msg *message.Message) {
	type_ := msg.Heads.Get(message.TYPE)
	switch type_ {
	case message.LOGIN:
		{
			usarename := msg.Heads.Get(message.USERNAME)
			if len(usarename) > 0 {
				time_ := msg.Heads.Get(message.TIME)
				if len(time_) > 0 {
					ti, err := strconv.Atoi(time_)
					if err == nil {
						this.liveTime = ti + this.liveTime
					} else {
						log.Debug("获取心跳时间失败", err)
					}
				}
			}
			core.AddUser(usarename, this)
			this.userId = usarename
			this.sendMessageBytes(message.LoginSuccess())
		}
	case message.MESSAGE:
		{
			touser := msg.Heads.Get(message.TO)
			_, err := core.SendMessage(touser, msg)
			if err==nil{
				this.SendMessage(message.SendSuccess(touser))
			}else{
				this.SendMessage(message.SendFail(touser))
			}
		}
	case message.LIVE:
		{
			this.sendMessageBytes(message.Live())
		}
	}
	this.SetReadDeadline()
}